﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using System.Collections.ObjectModel;
using System.Collections;
using System.Windows.Threading;
using System.Threading;

namespace SanctusSoftware.CcliSongSelectLib.Management
{

    public delegate void NoArgsDelegate();

    public class SongSelectDocumentLibraryManager : LibraryManager
    {

        #region Properties

        private readonly Dictionary<string, SongSelectDocument> _DocumentsDict = new Dictionary<string, SongSelectDocument>();
        private readonly ObservableCollection<SongSelectDocument> _Documents = new ObservableCollection<SongSelectDocument>();
        private ReadOnlyObservableCollection<SongSelectDocument> _ReadOnlyDocuments = null;
        private readonly object _ReadOnlyDocumentsLockObject = new object();

        public ReadOnlyObservableCollection<SongSelectDocument> Documents
        {
            get
            {
                lock (_ReadOnlyDocumentsLockObject)
                {
                    if (_ReadOnlyDocuments == null)
                    {
                        _ReadOnlyDocuments = new ReadOnlyObservableCollection<SongSelectDocument>(_Documents);
                    } 
                }
                return _ReadOnlyDocuments;
            }
        }

        protected override string FileSearchPattern
        {
            get
            {
                return "*.usr";
            }
        }

        #endregion

        Dispatcher _D = null;

        public SongSelectDocumentLibraryManager()
        {
            ((INotifyCollectionChanged)this.Files).CollectionChanged += new NotifyCollectionChangedEventHandler(Files_CollectionChanged);
            _D = Dispatcher.FromThread(Thread.CurrentThread);
        }

        void Files_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    AddDocuments(e.NewItems);
                    break;
                case NotifyCollectionChangedAction.Move:
                    // Don't Care
                    break;
                case NotifyCollectionChangedAction.Remove:
                    RemoveDocuments(e.OldItems);
                    break;
                case NotifyCollectionChangedAction.Replace:
                    RemoveDocuments(e.OldItems);
                    AddDocuments(e.NewItems);
                    break;
                case NotifyCollectionChangedAction.Reset:
                    break;
                default:
                    break;
            }
        }

        private void AddDocuments(IList files)
        {
            foreach (string file in files)
            {
                var doc = new SongSelectDocument();
                doc.Load(file);
                NoArgsDelegate del = delegate()
                {
                    _Documents.Add(doc);
                };
                _D.Invoke(del, null);
                _DocumentsDict.Add(file, doc);
            }
        }

        private void RemoveDocuments(IList files)
        {
            foreach (string file in files)
            {
                if (_DocumentsDict.ContainsKey(file))
                {
                    var doc = _DocumentsDict[file];
                    NoArgsDelegate del = delegate()
                    {
                        _Documents.Remove(doc);
                    };
                    _D.Invoke(del, null);
                    _DocumentsDict.Remove(file);
                }
            }
        }

    }
}
